package face.pay.open.file.service.impl;

import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.sdk.OSSUtils;
import com.face.pay.IPayConfigServer;
import com.face.pay.SecurityConfig;
import com.face.pay.WxApiConfig;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import face.pay.dao.FileInfoDao;
import face.pay.dao.OemConfigInfoDao;
import face.pay.dao.OemInfoDao;
import face.pay.entity.FileInfo;
import face.pay.open.file.service.IFileApiService;
import face.pay.open.server.CertficatesServer;
import face.pay.open.util.request.ApiRequestParam;
import face.pay.open.util.request.ErrorCode;
import face.pay.open.validate.ApiParamValidate;
import face.pay.util.FaceFileUtils;
import face.pay.util.ResultMessage;
import face.pay.util.bean.JavaBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.Consts;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.content.FileBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Auther: zkj
 * @Date: 2019/8/23 16:33
 * @Description:
 */
@Service
@Slf4j
public class FileApiServiceImpl implements IFileApiService {

    @Autowired
    private ApiParamValidate apiParamValidate;

    @Autowired
    private OemConfigInfoDao oemConfigInfoDao;

    @Autowired
    private OemInfoDao oemInfoDao;

    @Autowired
    private IPayConfigServer wxApiConfigServer;

    @Autowired
    private FileInfoDao fileInfoDao;

    @Autowired
    private CertficatesServer certficatesServer;


    @Override
    @Transactional
    public ResultMessage upload(String json) {

        log.info("图片上传请求");
        Integer code = ErrorCode.ERROR;

        String message  = "未知错误";

        Boolean flag= true;


        ApiRequestParam apiRequestParam  = apiParamValidate.parse(json);
        if(apiRequestParam!=null) {
            Integer oemId = apiRequestParam.getOemId();

            WxApiConfig config = wxApiConfigServer.getConfig(oemId);


            SecurityConfig securityConfig = config.getSecurityConfig();
            /**
             * 签名验证
             * 参数验证
             *
             */

            Map<String, String> data = apiRequestParam.getData();

            Boolean validate =  apiParamValidate.validate(data,apiRequestParam.getSign(),securityConfig);

            if(!validate){
                code = ErrorCode.SING_ERROR;
                message = ErrorCode.SING_ERROR_MESSAGE;
            }else {
                FileInfo fileInfo = (FileInfo) JavaBeanUtils.mapToBean(data, FileInfo.class);

                if(fileInfo!=null){
                    fileInfo.createFullName(oemId);
                    fileInfo.setOemId(oemId);
                    /**
                     * 数据验证
                     */

                    byte[] bytes = FaceFileUtils.hex2byte(fileInfo.getBody());


                    /**
                     * 上传oss
                     */
                    try {

                        log.info("上传OSS");
                        PutObjectResult putObjectResult = OSSUtils.putOSS(securityConfig.getEndPoint(), securityConfig.getAccessKeyId(), securityConfig.getAccessKeySecret(), securityConfig.getBucket(), fileInfo.getFullName(), bytes, false);

                    } catch (Exception e) {
                        log.error("OSS 上传失败",e);
                        code = ErrorCode.ALI_OSS_ERROR;
                        message = ErrorCode.ALI_OSS_ERROR_MESSAGE;
                        flag = false;
                    }
                    if(flag){

                        try {
                            log.info("上传OSS");
                            WXPayRequest wxPayRequest = new WXPayRequest(config);

                            String fullName = fileInfo.getFullName();
                            String type = fullName.split("[.]")[1];

                            File excelFile = File.createTempFile(UUID.randomUUID().toString(), "." + type);

                            FaceFileUtils.byteToFile(bytes, excelFile);


                            FileBody fileBody = new FileBody(excelFile, ContentType.create("image/jpg", Consts.UTF_8));

                            String domain = "api.mch.weixin.qq.com";

                            String urlSuffix = "/secapi/mch/uploadmedia";

                            String hash = DigestUtils.md5Hex(bytes);
                            Map<String, String> param = new HashMap<>(3);
                            param.put("media_hash", hash);
                            param.put("mch_id", config.getMchID());


                            String sign = WXPayUtil.generateSignature(param, config.getKey());

                            param.put("sign", sign);

                            String resultMessage = wxPayRequest.fileUpload(domain, urlSuffix, param, fileBody, 8000, 6000, true);

                            Map<String, String> result = WXPayUtil.xmlToMap(resultMessage);

                            log.info(resultMessage);
                            String success = result.get("return_code");
                            if ("SUCCESS".equals(success)) {
                                String result_code = result.get("result_code");
                                if ("SUCCESS".equals(result_code)) {
                                    /**
                                     * 成功
                                     */
                                    String media_id = result.get("media_id");
                                    fileInfo.setMediaId(media_id);
                                    this.fileInfoDao.insert(fileInfo);

                                    excelFile.delete();

                                    Map<String,Object> file =  new HashMap<>();

                                    file.put("file_id",fileInfo.getId());
                                    file.put("media_id",media_id);

                                    return ResultMessage.createSuccess("物料上传成功",file);

                                }
                            }else{
                                String error = result.get("err_code_des");
                                code = ErrorCode.WX_SEND_ERROR;
                                message = error;
                            }

                        }catch (Exception e){
                            log.error("微信调用失败");
                            code = ErrorCode.WX_SEND_ERROR;
                            message = ErrorCode.WX_SEND_ERROR_MESSAGE;
                        }
                    }
                }else{
                    code = ErrorCode.PARSE_ERROR;
                    message = ErrorCode.PARSE_ERROR_MESSAGE;
                }

            }


        }else {

            code = ErrorCode.PARSE_ERROR;
            message = ErrorCode.PARSE_ERROR_MESSAGE;
        }

         return  ResultMessage.createFail(message).setErrorCode(code);
    }
}
